package surreal.triviamaster.utilities;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import surreal.triviamaster.beans.Answer;
import surreal.triviamaster.beans.Category;
import surreal.triviamaster.beans.LikelyAnswer;
import surreal.triviamaster.beans.Question;

public class Utilities {
	/**
	 * Creates a list of categories based on the incoming jason data
	 */
	public static Category[] jsonToArrayCategories(String json) {
	    try {
	      JSONArray jsonArray = new JSONArray(json);
	      Category[] cats = new Category[jsonArray.length()];
	      for (int i = 0; i < jsonArray.length(); ++i) {
	        JSONObject jsonObject = jsonArray.getJSONObject(i);
	        cats[i] = new Category(jsonObject.getInt("id"), jsonObject.getString("category"));
	      }
	      return cats;
	    } catch (JSONException e) {
	      return null;
	    }
	  }
	
	public static void displayArray(Category[] cats) {
		for(int x=0; x<cats.length;x++)
			System.out.println(cats[x]);
	}
	
	/**
	 * Creates a list of categories based on the incoming jason data
	 */
	
	public static Question[] jsonToArrayQuestions(String json) {
		try {
			JSONArray jsonArray = new JSONArray(json);
	      	Question[] questions = new Question[jsonArray.length()];
	      	for (int i = 0; i < jsonArray.length(); ++i) {
	      		JSONObject jsonObject = jsonArray.getJSONObject(i);
	      		try {
					questions[i] = new Question(jsonObject.getInt("id"), jsonObject.getString("question"), false, -1, 0,"", jsonObject.getString("hint"), -1,-1);
				} catch (Exception e) {
					Log.d("Utilities Json to Question", TriviaMasterApplication.ERROR_INVALID_CHARACTERS);
					e.printStackTrace();
				}
	      }
	      return questions;
	    } catch (JSONException e) {
	      return null;
	    }
	}
	
	/**
	 * Creates a list of categories based on the incoming jason data
	 */
	
	public static Answer[] jsonToArrayAnswers(String json) {
		try {
			JSONArray jsonArray = new JSONArray(json);
			Answer[] aAs = new Answer[jsonArray.length()];
			
	      	for (int i = 0; i < jsonArray.length(); ++i) {
	      		JSONObject jsonObject = jsonArray.getJSONObject(i);
	      		aAs[i] = new Answer(jsonObject.getInt("id"), jsonObject.getInt("questionId"), jsonObject.getString("answer"));
	      	}
	      return aAs;
	    } catch (JSONException e) {
	    	System.out.println("error in json processessing acceptable asnwers");
	      return null;
	    }
	}
	
	/**
	 * Creates a list of categories based on the incoming jason data
	 */
	
	public static LikelyAnswer[] jsonToArrayLikelyAnswers(String json) {
		try {
			JSONArray jsonArray = new JSONArray(json);
			LikelyAnswer[] aAs = new LikelyAnswer[jsonArray.length()];
			
	      	for (int i = 0; i < jsonArray.length(); ++i) {
	      		JSONObject jsonObject = jsonArray.getJSONObject(i);
	      		aAs[i] = new LikelyAnswer(jsonObject.getInt("id"), jsonObject.getInt("questionId"), jsonObject.getInt("answerId"), jsonObject.getString("answer"));
	      	}
	      return aAs;
	    } catch (JSONException e) {
	    	System.out.println("error in json processessing acceptable asnwers");
	      return null;
	    }
	}
	
	/**
	 * Tests the string to make sure it only contains alphanumeric, spaces, and commas.
	 * @param var The variable to be tested
	 * @return True if the string can be uploaded
	 */
	public static boolean isValidToUpload(String var) {
		//MAKE sure the - is last inside the brackets
		//return var.matches("^[a-zA-Z0-9, '().-]*$");	
		return !var.matches("\"");	
	}
	
	/**
	 * Converts a list of questions into a json string
	 * 
	 * @return the string
	 */

	public static String convertQuestiontoJSON(Question[] qList) {
		JSONArray jsonArray = new JSONArray();
		for (int i = 0; i < qList.length; ++i) {
			JSONObject tmp = new JSONObject();
			try {
				tmp.put("id", qList[i].getId());
				tmp.put("correctlyAnswered", qList[i].getCorrectlyAnswered());
				jsonArray.put(tmp);
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		return jsonArray.toString();
	}
	/**
	 * Returns wither or not there is connection to the internet
	 * @param context
	 * @return
	 */
	
	public static boolean isNetworkAvailable(Context context) {
	    ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo info = manager.getActiveNetworkInfo();
	    return info != null && info.isConnected();
	  }
	/**
	 * Analyzes the current list of aAs and adds aAs to it that will make it more likely that users
	 * will guess the correct answer
	 * @param aAs
	 * @return
	 */
	public static String analyzeaAs(String aAstmp) {
		String[] aAsArray = aAstmp.split(";");
		ArrayList<String> aAs=new ArrayList<String>();
		
		for(int i=0;i<aAsArray.length;i++ ) {
			aAs.add(aAsArray[i]);
		}
		
		for(int i=0;i<aAsArray.length;i++ ) {
			aAs.addAll(analyze(aAs.get(i), false));
		}
		
		//deleting duplicates
		for(int i=0; i<aAs.size();i++) {
			for(int j=i+1; j<aAs.size(); j++) {
				if(aAs.get(j).equals((aAs.get(i)))) {
					aAs.remove(j);
					j--;
				}
			}
		}
		
		String toRet="";
		for(int i=0;i<aAs.size();i++) {
			if(toRet.equals("")) {
        		//if the aAs is empty just add the answer
				toRet=aAs.get(i);
        	} else {
        		//else add a delimiter before the answer
        		toRet+=";"+aAs.get(i);
        	}
		}
		
		return toRet;
	}
	
	/**
	 * Analyzes one string to find all the extended possibilities for acceptable answers.  When using recursion, 
	 * if the call is inside something that will get called again, use TRUE for isRecursive.
	 * @param string The string to be analyzed
	 * @param isRecursive Always use false when calling from an external method
	 * @return The ArrayList full of the aAs
	 */
	private static ArrayList<String> analyze(String aA, boolean isRecursive) {
		String naturalCase = aA;
		aA=aA.toLowerCase();
		ArrayList<String> aAs=new ArrayList<String>();
		
		//Starts with text
		if(aA.startsWith("the ")) {
			aAs.add(naturalCase.substring(4, aA.length()));
		}
		if(aA.startsWith("dr ")) {
			aAs.add(naturalCase.substring(3, aA.length()));
		}
		if(aA.startsWith("dr. ")) {
			aAs.add(naturalCase.substring(4, aA.length()));
		}
		if(aA.startsWith("a ")) {
			aAs.add(naturalCase.substring(2, aA.length()));
		}
		if(aA.startsWith("an ")) {
			aAs.add(naturalCase.substring(3, aA.length()));
		}
		
		//dealing with and
		if(isRecursive==false&&aA.contains(" and ")) {
			String tmp = naturalCase.substring(aA.indexOf(" and ")+5, aA.length()) + " and " + naturalCase.substring(0, aA.indexOf(" and "));
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		}
		
		//dealing with special characters
		
		/*
		 * Replace number if it is a lone number
		 * a number at the end of the answer
		 * or exactly the answer
		*/
		
		if(aA.contains("one ")) {
			String tmp = aA.replace("one ", "1 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" one")) {
			String tmp = aA.replace(" one", " 1");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("one")) {
			aAs.add(aA.replace("one", "1"));
		} 
		
		if(aA.contains("two ")) {
			String tmp = aA.replace("two ", "2 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" two")) {
			String tmp = aA.replace(" two", " 2");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("two")) {
			aAs.add(aA.replace("two", "2"));
		} 
		
		if(aA.contains("three ")) {
			String tmp = aA.replace("three ", "3 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" three")) {
			String tmp = aA.replace(" three", " 3");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("three")) {
			aAs.add(aA.replace("three", "3"));
		} 
		
		if(aA.contains("four ")) {
			String tmp = aA.replace("four ", "4 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" four")) {
			String tmp = aA.replace(" four", " 4");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("four")) {
			aAs.add(aA.replace("four", "4"));
		} 
		
		if(aA.contains("five ")) {
			String tmp = aA.replace("five ", "5 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" five")) {
			String tmp = aA.replace(" fine", " five");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("five")) {
			aAs.add(aA.replace("five", "5"));
		} 
		
		if(aA.contains("six ")) {
			String tmp = aA.replace("six ", "6 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" six")) {
			String tmp = aA.replace(" 6", " 6");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("six")) {
			aAs.add(aA.replace("six", "6"));
		} 
		
		if(aA.contains("seven ")) {
			String tmp = aA.replace("seven ", "7 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" seven")) {
			String tmp = aA.replace(" seven", " 7");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("seven")) {
			aAs.add(aA.replace("seven", "7"));
		} 
		
		if(aA.contains("eight ")) {
			String tmp = aA.replace("eight ", "8 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" eight")) {
			String tmp = aA.replace(" eight", " 8");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("eight")) {
			aAs.add(aA.replace("eight", "8"));
		} 
		
		if(aA.contains("nine ")) {
			String tmp = aA.replace("nine ", "9 ");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.endsWith(" nine")) {
			String tmp = aA.replace(" nine", " 9");
			aAs.add(tmp);
			aAs.addAll(analyze(tmp, true));
		} else if(aA.equals("nine")) {
			aAs.add(aA.replace("nine", "9"));
		} 
		
		return aAs;
	}
}
